This document is extracted from the upcoming book “Advanced Patterns of Enterprise Architecture”. Details on the release date and other pertinent facts about this and other works by Christopher G. Lasater can be seen at http://www.geocities.com/lasaterconsult.
About the Domain Object Project Template
What is Domain Object Architecture?
Why use the Domain Object approach?
Generating the Stored Procedures
Using the Code Generation Templates to Generate your Code
The most common architecture used in modern business development is the tiered architecture or as it has recently been named, the Domain Object pattern. It is simple to implement, easy to maintain, and above all easy to understand by a wide variety of skill sets. Most enterprise applications use this model in some fashion. The probable reason for its ubiquitous use in business applications stems from its overall simplicity and that the pattern follows a very traditional and well known model. Since most applications are about pushing, pulling and manipulating data, this pattern serves a wide variety of needs for all types of business. It is relatively simple in its overall application and can be implemented in various degrees of complexity. This model is usually known as domain object modeling or N- tiered architecture.
The pattern and example code I have created for this document is set up for a windows user interface type. Some of the decisions in the code are specific to this. So morphology of the pattern is expected. Since the example code for the test case in this document is specific to a problem, adapting the pattern to other conditions would not be hard; only the basic rules of the pattern need to be followed. If, for example, you were to adapt this pattern for a service oriented architecture or one that used transactions in code, you might replace the data layer with a DAL/DAC (data access layer/component) that supported transaction management. If you were dealing with serializing large numbers of records, the collections classes might be a bit cumbersome, so a more efficient (simpler) design might be appropriate; for instance a very light serializable class to replace the collections base or one that only returned the basic byte information from the records. Many other definitions for usability for the pattern come to mind, this I leave up to your creativity and imagination. Suffice it to say, this is a pattern, a basic definition for writing code, and adaptability is key. You will have to take the basic code examples I have provided, and create from them your own useable patterns for your business domain.
This template was written because I saw a lot of confusion and bad practices going on in the corporate business world surrounding software development, and I wanted to provide a common template for using this software pattern. I call this model for software design a pattern in this book, since I am defining a set of the attributes and principles it may contain.
The architecture used for this document is a formalized N-Tier architecture, which has hard separations between each tier using interfaces and factories to form conditional boundaries separating the code layers. Each layer has some separation, but the boundary between the user interface layer and Business Layer is a firm Façade type layer that allows peeks into useable system data via bind-able objects and collections which are passed in lieu of less specialized objects like a dataset. This was done purposefully, to minimize interpretations in data between the layers, while allowing intuitive functionality to be passed from one layer to another.
Template Driven Code Design
So, what is the template? Since we are using a pattern, then we can design a way to template the pattern. Since a pattern is a set way of building something, a template is a tool for allowing some basic data to be fed in to generate code that follows the guidelines of the pattern to be reproduced. In other words, I have provided for this document a template that will generate your code.
The pattern I will be introducing you to is based on these concepts:
· The code you generate will be based on record sets using basic CRUD database queries.
· The code will follow a basic data in - data out model, utilizing record set object modeling.
· Your tables will have referential integrity, or at least, primary keys.
These basic concepts allow the pattern to be produced and used, and especially rendered in code via a template that can gather the table schema data, and produce code from it. Everything that can be patterned can be generated using a template, so the methodology can exist as long as there is enough basic data to generate the code.
The first question to ask when using any architecture model or pattern is ‘why?’ Let’s discuss some reasons why you might or might not want to use the three tiered approach. As I said earlier, most business applications are about pushing to or pulling from a data source, and manipulating that data. So the first question you as a developer should ask is how complex will my data manipulation tasks become? If you can answer this question by saying that you want to pull known data from immutable (unchanging or unchangeable) objects and domains, and that the business rules and process will not need to change during runtime or will not change between iterations or releases of code, then you may be safe using the three tiered pattern.
Most data driven business applications implement the three tiered pattern in some form. It is easy to understand, has understandable and concentric layers of functionality, and has an easy to follow design. This is the least abstract pattern for architecture. The pattern has three basic layers: data, business logic and user interface. When beginning to implement this pattern you first need to look at its level of runtime flexibility. The 3-tiered pattern is most useful when you have known and immutable domain objects that will not change between release iterations (to production) and there is no need for more runtime flexibility in class relationships and domain object relationships.
But why use three tiers? There are many answers to this question. The most important to my mind is ease of maintainability, scalability, and portability. Ease of maintainability comes in the form of placing separated logic areas in an encapsulated domain, therefore limiting the scope of maintenance. Scalability is accomplished by allowing each tier to be responsible for only the functionality it needs to know about, making adding functionality to a tier easier, since the scope of changes will be smaller. Portability also is enhanced. Because the tiers are coupled as loosely as possible, the different tiers of code can be easily interchanged and do not rely on each other in an interwoven fashion. As well the Business Layer tier can be modeled to support either a win-forms user interface, a web front end, a web service or a variety of other input interfaces.
As I said before this model is very useful for a wide range of business data solutions. This is because the overall gist of the pattern is simple. Three layers, each doing specific duties, and with relatively static business logic, keeps things simple to understand and non-abstract in function. Since all class relationships between the tiers are fairly intuitive, the pattern makes scalability and maintenance between iterations a lot easier. One of the reasons for this is the encapsulation in each tier of specific logical duties. Data storage and retrieval are specific to the data source and are handled exclusively in the data tier. Algorithms and code to massage and manipulate the data in and out exist in the business tier. And functions specific only to the user interface experience keep the user interface tier very light and focused on displaying data to and receiving data from the user. Indeed, keeping things in the user interface simple and pushing that complexity down into the business layer tier gives the pattern a lot more flexibility than keeping business specific code in the user interface. One major example of this would be data specific rules. Let’s say you have a windows form class that contains a varied amount of data validation, and you wish to replicate all this validation in another page. Examine the example:
if(user.UserName == null || user.UserName.Length < 1)
throw new ArgumentException("Value cannot be an empty string or null.",
"UserName");
If you simply cut and pasted this validation code throughout the user interface layer then you have created a maintenance issue. The overall integrity of this validation code is tightly dependant on maintaining the code in each place it exists throughout the user interface. Changes to one section of the code will not assure that the same code in other places will always function the same.
Instead, let’s consider refactoring the validation code into a single place in the business tier. Doing this limits the maintenance to a single place in the Business Layer code. It also allows the business tier to handle these rules, instead of multiple code blocks in the user interface. This gives uniformity to the way these rules are applied, provides a single place to maintain the code, and makes the user interface lighter overall. By putting validation rules into the Business Layer tier you can easily reuse them for a multitude of uses. Also you give the control to the Business Layer for all validation instead of the user interface, which will ensure a single pass through point. If you have specialized validation needs (as in the case of required field validators) you can build access to the rules from your Business Layer object which can be used for that level of validation.
Inside the Business Layer rules engine when we parse through a collection of user objects checking for data to validate a rule we can then add validation messages as needed to tell the user interface about problems we encounter, or any other information:
//In the Business Tier Rules Validation Engine...
if(user.UserName == null || user.UserName.Length < 1)
user.ValidationMessages.Add(new ValidationMessage(
ValidationLevel.Exception, "UserName", "Value cannot be null or empty string."));
//the ValidationLevel parameter shows the level of exception.
//In this case it is a business rule attached to a message.
We can see that the UserName property is checked for validation. If the UserName property is null or empty string, then our business rules state that we are to add a validation message. Since our business rules state we want to send messages to the user interface to tell it if a validation failed, we will attach a message and a parameter (ValidationLevel) for the level of exception to allow the user interface some decision making in how to display or deal with the message.
Our user interface (which for this example is a web page) now can get a collection of Business Layer objects containing the data for a series of users each with their own validation messages and feed this collection into a web user control. Below we see that the user interface code to do this is fairly simple. We call a collection in the form of an interface with a concrete collection type behind it from a factory and feed the resulting collection into a web control:
private void Page_Load(object sender, System.EventArgs e)
{
IUsersDataBL users = Factory.GetUsers();
UserRepeater.Datasource = users;
}
In our markup we want to display our UserName properties value. In this case we want to use a repeater control to display a list of users and any validation messages. We get our validation messages through the validation collection inside the Business Layer class:
<repeater id="UserRepeater" runat=server >
<ItemTemplate>UserName is
<% #((IUserDataBL)Container.DataItem).UserName ) %>
<br>
<% if(((IUserDataBL)Container.DataItem).HasExceptionValidationMessages)
{
foreach(BusinessLayer.BL.Validation.ValidationMessage message in
((IUserDataBL)Container.DataItem).ValidationMessages)
if(message.FieldName.Equals("UserName"))
Response.Write(message.FieldName + " " + message.Message + "<BR>");
}%>
</Itemtemplate>
</repeater>
This displays whether the UserName property and validation messages for Business Layer property. We take the UserName property from the IUserDataBL object inside the collection used for the repeater object’s data source and use it to display the desired text in the user interface. The IUsersDataBL collection can even be mapped in the user interface to a control attribute (like Visible or the FontColor) for display.
.Net 2.0 seems more attuned to user interface control property data binding in that it makes use of property binding in its data binding structure. In other words .Net 2.0 can bind a value from a data object to a specific property on a user interface control.
Now if our business rule states that if the UserName property is null or empty then this condition was to cause an actual validation exception and we needed to check it (lets say to go to a error page) we could for instance get a user Business Layer object and check its validation messages. So we can check for a null value in our Business Layer rules engine, which hands us up a series of validation messages. We could even have types of validation messages which could tie page urls, images, specialized globalization text, etc to each validation type and message. If it has some messages then the user interface could use them and make its own logic to redirect to an error page:
//get a user object from the factory inside the BL
IUserDataBL user = Factory.GetUser(int id);
//If the user object has validation messages then we build a string and send this
//to an error page to display to the user…
if(user.HasExceptionValidationMessages)
{
string messages = string.Empty;
foreach(ValidationMessage message in user.ValidationMessages)
if(message.ValidationLevel == ValidationLevel.Exception)
//check the exception level from the validation message
//and if it reaches the desired level then ad it to the
//message queue
messages += "," + message.Text;
Response.Redirect(string.Format("~/ErrorPage.aspx?Message={0}",
Server.UrlEncode(messages)));
}
The test case I am using for the example will have a lot of bells and whistles that you may or may not need for your projects. The test case code examples are actual working code examples that can easily be adapted into any business code model that it may apply to. Except for the basic structure you can be assured to be safe when removing or even enhancing each aspect or piece of the overall pattern. This is expected to help you fit the pattern into your business model.
This entire pattern with all its layers and tiers might seem too complex to write for many programmers, too many widgets, too many rules to follow, too many points of failure on the part of the developer. The problem is one of managing the complexity of the code, more than the idea of it. That is where maintenance issues and complexity in development arise. The onus of any organization that develops custom code is that there has to be an agreement and a basic knowledge base with in the team, organization or company. Usually this does not exist, or only partly exists. Even if you have a team of top programmers, each one must be extra diligent when writing code, to make sure they follow the rules. Usually code conventions are loose if non-existent, and are dependant on either developer diligence or an architect to mandate and maintain the integrity of the code written. This can become a daunting task, especially in large companies. Code conventions can differ between projects, teams, or even assemblies. Organizing enforcement of any kind of standardization has had a lot of methodology and text applied to accomplishing this task, but one simple fact rises out of this process. That fact is that people make mistakes. No matter who you are, from Bill Gates to the developer starting his or her first job, you are going to make mistakes in your code. And the more code you write, and this applies double to high code volume or fast paced project iterations, the more chance for mistakes.
It seems that the weakest point in project development is the human element. The weakest point in the development process is me, you and every developer on your team. A development team is only as strong architecturally as its least knowledgeable member, and even the brightest and best are, well, only human.
However, what if I told you if you could do two simple things you could make the human element perform as it should. The human element does not need to create and maintain menial code and development jobs. The human element does not need to re-write code repeatedly (which is especially true when you pattern, you are simply re-using a standard code base). What the human element is good at is creating a design for an architectural template for a pattern that can be generated and re-generated repeatedly with different data from different sources.
The pattern we have covered in this document was meant to do exactly that. It was meant to be auto-generated using a template tool.
One of the two things you have to do to template and then re-generate any code is to first standardize the code into a recognized pattern. This can be done several ways, but most developers can see reusable code if they put their minds to it.
The second thing you must do is to create, using a tool, a template which can re-generate this pattern for different data points. These data points, like tables, stored procedures, variables, or any data that, when changed, should not change the overall functionality of the pattern, but instead supply the needed information to generate the code that corresponds with the data input.
For the example I am using in this pattern, I have done just such a thing. The first step is to find a tool to generate our template. The tool I am using for the example code and the one with which the example code is written with is CodeSmith 4.0. I use this to run the actual template project, which gives me the ability to generate code from the pattern, from a basic user interface down to the stored procedures.
To help you understand and be able to generate your code from this pattern you will need to download a trial (unless you have a license) copy of CodeSmith from their site http://www.codesmithtools.com/. The next step is to download or access from a companion CD, the example template code I have provided for this book, which will give you a working example of the template code we will use. You also have to have Visual Studio 2005 and .NET 2.0 to compile and examine the example code.
The first step in using the template is to compile them using your CodeSmith 4.0 IDE. Each of these projects must be compiled, before the main project (DomainObjectsProject.csp) will compile and run.
· StoredProcedures/GenerateAllProcs.cst
· MDIForms/MDIFormsProject.cst
· FormsUIComponent/FormsUIErrorProviderProject.cst
· DataLayer/DataLayerProject.cst
· BusinessLayer/BusinessLayerProject.cst
· ProjectCompile.cst
After you have compiled each of these sub projects using the IDE, then you can run the main project (DomainObjectsProject.csp).
The next step in using the template is to determine which tables you want to use for your project. Once you have determined this, and made sure all tables have at least a primary key that increments its own identity seed (see Figure 3.11), or in the case of a unique identifier key, which can set its own key or have one set for it, does not set its own key. If these conditions cannot be met then generating your stored procedures using this template is not recommended without modifying the stored procedure generation templates.

Figure 3.9
Generating the stored procedures is not difficult, but to get the most out of the code generation templates, the rules and definition contained in the generated stored procedure code should be followed without much deviation.
To actually generate the stored procedure you will need to
create a template folder shortcut to the place where the templates for this document
are on your drive (use the
button). You then
can either open the CodeSmith Studio and find the file GenerateAllProcs.cst
and execute the procedure (see Figure 3.12), or simply double click the file
from Windows Explorer to pull up the execution interface.

Figure 3.10
When you open the interface from the file GenerateAllProcs.cst, you will notice a grid bag layout like in the project. You will need to set certain variables that will tell the template what database, table and columns you wish to use as query index keys, and naming prefixes.
These properties are:
· SourceTable – This is the table that you wish to run the template against to generate the three stored procedures (Select Collection, Select Record By ID, Update-Insert-Delete).
· AutoExecuteScript – Indicates whether the script will be executed on the database after generation.
· ExcludedColumns – Indicates columns which are to not to be included in the query.
· IncludeDropStatement – Indicates that a stored procedure drop statement be generated. Since the stored procedures are generated as CREATE statements, this is allowed as an optional parameter.
· KeyColumns – This is a string collection list of any key columns to be used in the collection select query to pull records. The single record query always uses the primary key to pull only the single row for that key.
· ProcedureDescription – This will put a description in the header of the stored procedure.
· ProcedurePrefix – This is the prefix that will help identify the stored procedure for a particular code base or application. Example is aposa_ which would name procedures as aposa_GetUserData.sql
· TablePrefix - If this prefix is found at the start of a table name, it will be stripped off.
· OutPutDirectory – The directory in which to output the stored procedure scripts. If the AutoExecuteScript indicator is on, the script files are still generated, as files with the .sql extension.

Figure 3.11
The Source Table property is the main property for this template, and is a mandatory one. Set this using the data source selection interface (see Figure 3.13 below), which will allow you to choose your database (or add one using a connection string) and your table you wish to execute the template against. Remember, the data in the table is never accessed, only the schema or meta-data, so there is little need for concern when looking at tables with large amounts of data in them.

Figure 3.12
Three stored procedures will be generated. The first will be a select query to return a single record by primary key. The second will be a select query to return records for a collection either by the columns specified in KeyColumns string collection of the template, or all records if no keys are specified. The third query will act as our data modifier, providing access to insert, update and delete functions. The output stored procedures are illustrated in detail in the Data Layer section in this document.
There is one other aspect of the stored procedure that bears scrutiny. Since CodeSmith 4.0 supports a code merge strategy, I provide a section for version update notes that gets generated when the query is first generated. Any text put between the region tags (as seen in the example below), should not be overwritten, as long as the IncludeDropStatement property on the template is set to false.
--region RevisionLog
***************************** Revision Log **********************************
Version Date Revised By Description / WO#
-------- ---------- --------------- ---------------------------------------
*****************************************************************************/
--endregion
The main way of generating code for our pattern is by getting the data from a data source, like a database. All business specific classes are generated from record sets which are defined by stored procedures within the target database. Since each record set is defined by a stored procedure or up to three stored procedures, the actual code generated will be an extension of that data relationship. There is one mandatory stored procedure for the collection select query, one optional stored procedure for the individual record select query and one optional stored procedure for the update query for a single record.
The template generates the code by reading an xml file, which we talked about in the main project template and indicated by a project property ProcedureMap, which is a directory path to the xml file containing the record set data.
This xml file we will now examine. The overall markup of the file we see below, with the RecordSets node minimized for clarity. As you can see in the example markup xml, the xml file maps to a xml schema file named ProceduresToMap.xsd. This schema file (see Figure 3.13) sets the structure for the xml and for the template, which allows the template to read as code the individual nodes by name and function. This is important because each node needs to be read in sequence and by name to retrieve the different data points for each record set.
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ProceduresToMap.xsd">
<NameSpace>Test</NameSpace>
...
</RecordSets>
</Project>

Figure 3.13
As we can see above the xml schema defines a node called project, which in turn defines nodes NameSpace and RecordSets. The NameSpace node is ignored but the RecordSets node is a collection node that defines each record set. Each record set definition consists of a name, which will be the base name of the generated record set objects, and node definitions for three stored procedure nodes.
If we look at the first node in the xml we see the definition for the first record set to be generated. The order of the record sets is not important. The Name node contained in the RecordSet node is the singular name for the entire record set. As an example, if you were going to build a record set from the stored procedures we examined earlier in the document for the User table, we would call this record set ‘User’ since that would correspond to the underlying table. That would cause the template to create collection classes and interfaces for the Data Layer and Business Layer named IUsersBL -UsersBL and IUsersDL - UsersDL and record set classes named IUserBL -UserBL and IUserDL - UserDL. The User Interface template would also generate a MDI Form grid form class, as well as ‘add’ and ‘edit’ screens. The name you use should always be singular.
Notice in the markup example below the structure of the UpdateStoredProcedure node. There is a node called ExcludedFromRules, and a node called Command. The Command node is how the template will read the underlying schema and this node has two sub-nodes to indicate the stored procedure owner and the stored procedure name. If this stored procedure is not set to the update/insert/delete stored procedure, then no schema data is read, and the UpdateStoredProcedure node is ignored. The ExcludedFromRules node will be a comma delimited string of the property names (or column/parameter names) that you wish the rules class generation for the Business Layer rules engine to ignore.
<RecordSets>
<RecordSet>
<Name>User</Name>
<UpdateStoredProcedure>
<Command>
<Owner>dbo</Owner>
<Name>aposa_SetUserData</Name>
</Command>
<ExcludedFromRules>UserID,IsActive</ExcludedFromRules>
</UpdateStoredProcedure>
The next node to examine is the SelectStoredProcedure node, which is the node used to indicate the single record select query. The basic structure of the node is the same, the only difference is that the Command.Name node should be filled in with the name of the single record select query.
<Command>
<Owner>dbo</Owner>
<Name>aposa_GetUserData</Name>
</Command>
<ExcludedFromRules></ExcludedFromRules>
</SelectStoredProcedure>
The last node is the only node that is mandatory. This was done because sometimes there is a need for record sets that lookup data only and have no need to update their underlying data structures. The structure is exactly the same as the first two, and the only difference is that the Command.Name node should be filled in with the name of the collection select query.
<SelectCollectionStoredProcedure>
<Command>
<Owner>dbo</Owner>
<Name>aposa_GetUserData</Name>
</Command>
<ExcludedFromRules></ExcludedFromRules>
</SelectCollectionStoredProcedure>
</RecordSet>
Other record set nodes can be added as are needed, to have any number of structures that make up record sets. Each RecordSet node must conform to the schema file named ProceduresToMap.xsd.
<RecordSet>
<Name>Product</Name>
........
</RecordSet>
Now that your xml has been made ready, we can move ahead to our project, which will run against the xml file and generate our code from the four main templates.
Now that we have a basic understanding of how to build inputs for our template and what each part of those inputs look like, lets take a look at actually how the template works to generate all that cool code for the Domain Object pattern. This is where things get really high speed, in that your code will seem to write itself.
The first step in designing templates in CodeSmith is to design a project. Our project has a default template class and one default output. Below we can see the user interface CodeSmith provides for viewing the overall project.

Figure 3.14
The project file is really just an xml file with a CodeSmith extension on it. Below we see the project as it appears in raw xml markup.
<?xml version="1.0"?>
<codeSmith xmlns="http://www.codesmithtools.com/schema/csp.xsd">
<defaultTemplate path="ProjectCompile.cst" />
<propertySets>
<propertySet template="ProjectCompile.cst">
<property name="ProcedureMap">ProceduresToMap.xml</property>
<property name="UserInterfaceProjectGuid">
697299bb-a1ea-4046-88e0-80ff83888148
</property>
<property name="DataLayerProjectGuid">
cb2c8c2b-05a4-45c8-bc8b-432bac261ca5
</property>
<property name="OutPutDirectory">
..\MDIForms Generated 3 Tier Example\
</property>
<property name="FormsUIComponentProjectGuid">
0e1b985b-ea82-4a26-b33d-be421d07487f
</property>
<property name="TypeOfUserInterface">MDIForm</property>
<property name="CompanyName">Your Company Name</property>
<property name="CleanDirectories">False</property>
<property name="OutputFile">
..\MDIForms Generated 3 Tier Example\ProjectCompile.log
</property>
<property name="ProjectVersion">1.0.0.1</property>
<property name="SolutionProjectGuid">
a78e5bbf-eb6a-4d1f-8adb-790c587bb119
</property>
<property name="GenerateUI">True</property>
<property name="ProjectDescription">
Test Project Template
</property>
<property name="CanHaveNullablePrimitives">False</property>
<property name="CompanyNameSpace">APOSA</property>
<property name="BusinessLayerProjectGuid">
f9dcc057-a1d7-43cb-b37c-689127b2098e
</property>
<property name="TargetDatabase">
<connectionString>
SERVER=ANYDATABASE;DATABASE=APOSA;UID=testUser;PASSWORD=test;
</connectionString>
<providerType>
SchemaExplorer.SqlSchemaProvider,SchemaExplorer.SqlSchemaProvider
</providerType>
</property>
<property name="ProjectNameSpace">Test</property>
<property name="GenerateSolution">True</property>
</propertySet>
</propertySets>
</codeSmith>
The project is how we will set up basic things like the company identifiers, project name, namespace and version and a list of other .NET project specific and non-data specific configuration information. I provide a basic list of these properties below.
· ProjectGuid – This is a non-editable field which generates the .NET project unique identifier.
· CanHaveNullablePrimitives – This indicates whether the primitive data types for business data property variables can be nullable, a feature of .NET 2.0
· CompanyName – This will go in the AssemblyInfo.cs and is used for any manifests created.
· CompanyNameSpace – This is the company initials or name (no spaces) that will appear before all namespace(s) in the project(s). Example: YourCompany.ProjectName.BusinessLayer….
· ProjectDescription - This will go in the AssemblyInfo.cs and is used for any manifests created.
· ProjectNameSpace – This is the name of the overall project you are working on. Example: YourCompany.ProjectName.BusinessLayer….
· ProjectVersion – the current version of the project when this code is generated.
· CleanDirectories – Indicates whether or not to clean the output directory and delete all code before generation. If you are using the merge strategy and have existing code written in the regions, this should be set to false, so developer code does not get deleted.
· GenerateSolution – This indicates whether or not to generate a solution file for the projects. If your solution contains projects or references that are not part of the template, set this to false.
· GenerateUI – This indicates whether a default generic user interface project will be generated. This is a tool in the template that will generate a basic Web, MDI Forms or Windows Forms application for each of your tables or stored procedures that make up a record set.
· TargetDatabase – This is a CodeSmith required field, and determines which database to search in for all the schemas, stored procedures and table definitions.
· TypeOfUserInterface – This indicates which type of user interfaces to create, Web, MDI Forms or Windows Forms. The default is MDI Forms. Actually for this example, I only created a MDI forms template.
· OutPutDirectory – This is the directory where the generated code will be placed.
· ProjectGuid, BusinessLayerProjectGuid , DataLayerProjectGuid, FormsUIComponenetProjectGuid, UserInterfaceProjectGuid , SolutionProjectGuid – These are used to generate the project and should be ignored.
· ProcedureMap – This is the directory where the xml file is located that will tell us from which stored procedures we should generate our code and defines our record sets (see ‘Defining Record Sets’ a little later in the document).
· OutputFile – This is the directory where the log file for the generated code will go.

Figure 3.15
In the figure above we see most of the properties displayed in a grid bag on a form. This is a form that CodeSmith provides to view Project Template details. For our project we have a main project template, which compiles and generates code using sub-templates for each project, the solution, and all supporting files.
Once we have set up all our variables for our project and after your xml file is properly created and filled with all the names of the stored procedures for each record set, the project template to generate the code can come into play to help generate our code.

Figure 3.16
The template can be run in the CodeSmith Studio application or run by double clicking the project in Windows Explorer. The menu item in the CodeSmith Studio that is named ‘Generate Outputs’ will begin the code generation process.